Completed
Push — master ( b3de34...d68fb4 )
by Andres
40s
created

angular.controller(ꞌct_exoticꞌ)   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
nc 1
dl 0
loc 1
rs 10
nop 2
1
/**
2
 exotic
3
 Component that handles the exotic matter and prestige logic.
4
 It includes exotic matter production, exotic upgrades, and infusion of
5
 subatomic particles to boost exotic production.
6
 A prestige erases the progress of a single element, and produces exotic
7
 matter for said element.
8
9
 @namespace Components
10
 */
11
'use strict';
12
13
angular.module('game').component('exotic', {
14
  templateUrl: 'views/exotic.html',
15
  controller:  'ct_exotic',
16
  controllerAs: 'ct'
17
});
18
19
angular.module('game').controller('ct_exotic', ['state', 'format', 'visibility', 'upgrade', 'data', 'util',
20
  function (state, format, visibility, upgrade, data, util) {
21
    let ct = this;
22
    ct.state = state;
23
    ct.data = data;
24
    ct.util = util;
25
    ct.format = format;
26
    ct.infuse = {};
27
    let sortFunc = upgrade.sortFunctions(data.exotic_upgrades);
28
    ct.cache = {breakdown:{}};
29
30
    ct.update = function(player) {
31
      refresh(player);
32
    };
33
34
    /* Refreshes the values in the cache */
35
    function refresh(player){
36
        ct.cache.breakdown = {};
37
        for(let slot of player.element_slots || []){
38
          if(!slot){
39
            continue;
40
          }
41
          ct.cache.breakdown[slot.element] = ct.exoticProduction(slot.element);
42
        }
43
    }
44
45
    /* Exotic production is a function of the different resources of each
46
    element. Additionally, multi-element molecules count double, once for
47
    each participating element. */
48
    ct.exoticProduction = function(element) {
49
      let breakdown = {};
50
      for (let resource of data.elements[element].includes) {
51
        if (!state.player.resources[resource].unlocked ||
52
            !state.player.statistics.exotic_run[element] ||
53
            typeof state.player.statistics.exotic_run[element][resource] === 'undefined') {
54
          continue;
55
        }
56
        let production = {};
57
        for (let elem in data.resources[resource].elements) {
58
          if(!state.player.statistics.exotic_run[elem]){
59
             continue;
60
          }
61
          let numberAtoms = data.resources[resource].elements[elem];
62
          let prod = prestigeFormula((state.player.statistics.exotic_run[elem][resource] || 0)*numberAtoms);
63
64
          let args = {
65
            production: prod,
66
            resource: resource
67
          };
68
69
          upgrade.executeAll(data.exotic_upgrades, state.player.exotic_upgrades[elem], ['production', 'exotic'], args);
70
71
          // extract back the value from applying the upgrades
72
          let newExotic = data.elements[elem].exotic;
73
          production[newExotic] = (production[newExotic] || 0) + args.production;
74
        }
75
        for (let key in production) {
76
          // we adjust the infusion
77
          production[key] = Math.floor(production[key]*ct.totalInfuseBoost());
78
        }
79
        breakdown[resource] = production;
80
      }
81
82
      return breakdown;
83
    };
84
85
    ct.productionSum = function(element){
86
      let production = ct.cache.breakdown[element] || {};
87
      let sum = {};
88
	    sum[data.elements[element].exotic] = 0;
89
      for(let resource in production){
90
        for(let elem in production[resource]){
91
          sum[elem] = sum[elem]+production[resource][elem] || production[resource][elem];
92
        }
93
      }
94
      return sum;
95
    };
96
97
    function prestigeFormula(resource){
98
      resource = resource || 0;
99
      let production = Math.pow(Math.E,(-0.5+Math.sqrt(0.25+0.8686*Math.log(resource/1e6)))/0.4343) || 0;
100
      return Math.round(Math.max(0, production));
101
    }
102
103
    ct.exoticPrestige = function(index) {
104
      let slot = state.player.element_slots[index];
105
      let production = ct.productionSum(slot.element);
106
107
      for (let key in production) {
108
        util.addResource(state.player, 'dark', key, production[key]);
109
      }
110
111
      for(let resource in ct.infuse){
112
        state.player.resources[resource].number = Math.max(0, state.player.resources[resource].number-ct.infuse[resource]);
113
      }
114
115
      upgrade.resetElement(state.player, slot.element);
116
117
      // we deactivate reactions and redoxes
118
      for (let reaction of slot.reactions) {
119
        reaction.active = false;
120
      }
121
122
      for (let redox of slot.redoxes) {
123
        redox.active = false;
124
      }
125
126
      // we cache them in case players want to pick up the same element
127
      // the cache only lasts the current session
128
      state.reactionsCache[slot.element] = slot.reactions;
129
      state.redoxesCache[slot.element] = slot.redoxes;
130
131
      state.player.element_slots[index] = null;
132
      state.player.statistics.exotic_run[slot.element] = {};
133
    };
134
135
    ct.buyExoticUpgrade = function(name, slot) {
136
      let price = data.exotic_upgrades[name].price;
137
      let currency = data.elements[slot.element].exotic;
138
      upgrade.buyUpgrade(state.player,
139
        state.player.exotic_upgrades[slot.element],
140
        data.exotic_upgrades[name],
141
        name,
142
        price,
143
        currency);
144
    };
145
146
    ct.setPercentage = function(resource, percentage) {
147
      ct.infuse[resource] = Math.floor(state.player.resources[resource].number*(percentage/100));
148
    };
149
150
    ct.fixNumber = function(resource) {
151
      ct.infuse[resource] = Math.max(0, Math.min(state.player.resources[resource].number, ct.infuse[resource]));
152
    };
153
154
    /* This function checks that values inserted in the text boxes are
155
    valid numbers */
156
    ct.isValidInfusion = function() {
157
      let valid = true;
158
      for(let resource in ct.infuse){
159
        valid = valid && Number.isFinite(ct.infuse[resource]);
160
      }
161
      return valid;
162
    };
163
164
    ct.infuseBoost = function(resource) {
165
        let number = Math.min(ct.infuse[resource], state.player.resources[resource].number);
166
        if(number === 0){
167
          return 1;
168
        }
169
        // log adds diminishing returns to the infusion
170
        return 1 + Math.log(number)/Math.log(1.25)*ct.data.constants.INFUSE_POWER;
171
    };
172
173
    /* The infusion boosts are multiplicative with respect to each other */
174
    ct.totalInfuseBoost = function() {
175
      let total = 1;
176
      for(let resource in ct.infuse){
177
        total *= ct.infuseBoost(resource);
178
      }
179
      return total;
180
    };
181
182
    ct.visibleExoticUpgrades = function(slot) {
183
      return visibility.visible(data.exotic_upgrades, isExoticUpgradeVisible, slot, sortFunc[state.player.options.sortIndex]);
184
    };
185
186
    function isExoticUpgradeVisible(name, slot) {
187
      return visibility.isUpgradeVisible(name, slot, data.exotic_upgrades[name]) &&
188
          (!state.player.options.hideBought || !state.player.exotic_upgrades[slot.element][name]);
189
    }
190
191
    ct.visibleSubatomic = function() {
192
      return visibility.visible(data.resources, isSubatomicVisible, '');
193
    };
194
195
    function isSubatomicVisible(name) {
196
      if (!state.player.resources[name].unlocked) {
197
        return false;
198
      }
199
200
      if(data.resources[name].type &&
201
         data.resources[name].type.indexOf('subatomic') !== -1){
202
          return true;
203
      }
204
205
      return false;
206
    }
207
208
    state.registerUpdate('exotic', ct.update);
209
	  refresh(state.player);
210
  }
211
]);
212